function FileProgress (file, targetID) {
    var doc = document;
    this.fileProgressID = file.id;
    this.opacity = 100;
    this.height = 0;
    this.fileProgressWrapper = doc.getElementById(this.fileProgressID);

    if (!this.fileProgressWrapper) {
        this.fileProgressWrapper = doc.createElement('div');
        this.fileProgressWrapper.className = 'progressWrapper';
        this.fileProgressWrapper.id = this.fileProgressID;
        this.fileProgressElement = doc.createElement('div');
        this.fileProgressElement.className = 'progressContainer';

        var progressCancel = doc.createElement('a');
        progressCancel.href = '#';
        progressCancel.className = 'progressCancel'
        progressCancel.appendChild(doc.createTextNode('x'));

        var progressText = doc.createElement('span');
        progressText.className = 'progressName';
        progressText.appendChild(doc.createTextNode(file.name));

        var progressSize = doc.createElement('span');
        progressSize.className = 'progressSize';
        progressSize.appendChild(doc.createTextNode(file.size/1024 < 1024 ? (file.size/1024).toFixed(1) + ' KB' : (file.size/1024/1024).toFixed(2) + ' MB'));

        var pBar = doc.createElement('div');
        pBar.className = 'progressBarBack';

        var progressBar = doc.createElement('div');
        progressBar.className = 'progressBarInProgress';

        pBar.appendChild(progressBar);

        var progressStatus = doc.createElement('div');
        progressStatus.className = 'progressBarStatus';
        progressStatus.innerHTML = '&nbsp;';

        this.fileProgressElement.appendChild(progressCancel);
        this.fileProgressElement.appendChild(progressText);
        this.fileProgressElement.appendChild(progressStatus);
        this.fileProgressElement.appendChild(pBar);
        this.fileProgressElement.appendChild(progressSize);

        this.fileProgressWrapper.appendChild(this.fileProgressElement);

        doc.getElementById(targetID).appendChild(this.fileProgressWrapper);
    } else {
        this.fileProgressElement = this.fileProgressWrapper.firstChild;
    }

    this.height = this.fileProgressWrapper.offsetHeight;

}

FileProgress.prototype.setProgress = function (percentage) {
    this.fileProgressElement.className = 'progressContainer green';
    this.fileProgressElement.childNodes[3].childNodes[0].className = 'progressBarInProgress';
    this.fileProgressElement.childNodes[3].childNodes[0].style.width = percentage + '%';
};

FileProgress.prototype.setComplete = function () {
    this.fileProgressElement.className = 'progressContainer blue';
    this.fileProgressElement.childNodes[3].className = 'progressBarComplete';
    this.fileProgressElement.childNodes[3].style.width = '';
};

FileProgress.prototype.setError = function () {
    this.fileProgressElement.className = 'progressContainer red';
    this.fileProgressElement.childNodes[3].className = 'progressBarError';
    this.fileProgressElement.childNodes[3].style.width = '';
};

FileProgress.prototype.setCancelled = function () {
    this.fileProgressElement.className = 'progressContainer';
    if (this.fileProgressElement.childNodes[3]) {
        this.fileProgressElement.childNodes[3].className = 'progressBarError';
        this.fileProgressElement.childNodes[3].style.width = '';
    }

    var oSelf = this;
    setTimeout(function () {
        oSelf.disappear();
    }, 200);
};

FileProgress.prototype.setStatus = function (status) {
    this.fileProgressElement.childNodes[2].innerHTML = status;
};

FileProgress.prototype.removeDelIcon = function () {
    $(this.fileProgressElement.childNodes[0]).remove();
};

FileProgress.prototype.toggleCancel = function (show, swfUploadInstance, fileCallback) {
    this.fileProgressElement.childNodes[0].style.visibility = show ? 'visible' : 'hidden'; 
    if (swfUploadInstance) {
        if (fileCallback) {
            this.fileProgressElement.childNodes[0].onclick = function(){
                fileCallback();
            }
        } else {
            var fileID = this.fileProgressID;
            this.fileProgressElement.childNodes[0].onclick = function () {
                swfUploadInstance.cancelUpload(fileID);
                return false;
            };
        }
    }
};

FileProgress.prototype.disappear = function () {

    var reduceOpacityBy = 15,
        reduceHeightBy = 4,
        rate = 30; // 15 fps

    if (this.opacity > 0) {
        this.opacity -= reduceOpacityBy;
        if (this.opacity < 0) {
            this.opacity = 0;
        }

        if (this.fileProgressWrapper.filters) {
            try {
                this.fileProgressWrapper.filters.item('DXImageTransform.Microsoft.Alpha').opacity = this.opacity;
            } catch (e) {
                this.fileProgressWrapper.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + this.opacity + ')';
            }
        } else {
            this.fileProgressWrapper.style.opacity = this.opacity / 100;
        }
    }

    if (this.height > 0) {
        this.height -= reduceHeightBy;

        if (this.height < 0) {
            this.height = 0;
        }

        this.fileProgressWrapper.style.height = this.height + 'px';
    }

    if (this.height > 0 || this.opacity > 0) {
        var oSelf = this;
        setTimeout(function () {
            oSelf.disappear();
        }, rate);
    } else {
        //this.fileProgressWrapper.style.display = 'none';
        $(this.fileProgressWrapper).remove();

        if (!$('#fsUploadProgress').children().length) {
            $('.upload-list, .opt-btns').addClass('hidden');
        }
    }
};
